<template>
  <div class="service-node">
    <el-form label-position="top" :rules="rules" label-width="80px" :model="formData" ref='nodeForm'>
      <el-form-item label="服务执行策略" prop="executionOrder" class="bont">
        <el-select v-model="formData.executionOrder" @change="triggerExecutionOrder" placeholder="请选择">
          <el-option label="按顺序依次执行" value="0"></el-option>
          <el-option label="随机选择其中一项服务执行" value="1"></el-option>
        </el-select>
      </el-form-item>
      <div class="service-title">
        <span>所要执行的服务</span>
      </div>
      <!-- 服务项列表 -->
      <transition-group name="drag" class="service-list" tag="div" key="drag">
        <div v-for="(item, index) in formData.serviceSequence" @dragenter="dragenter($event, index)" @dragover="dragover($event, index)" @dragstart="dragstart($event, index)" draggable :key="item.serviceKey" class="service-item">
          <div class="sort-bg"></div><!-- 原生拖拽svg支持度较低 此处用背景图代替 -->
          <span class="service-name">{{ item.serviceName }}</span>
          <el-select v-if='!!index && formData.executionOrder === "0"' v-model="item.delayType" placeholder="请选择" class="select-execute">
            <el-option label="在前一项开始后" value="executeStart"></el-option>
            <el-option label="在前一项结束后" value="executeEnd"></el-option>
          </el-select>
          <span v-if='!!index && formData.executionOrder === "0"' class="type-suffix">延迟</span>
          <el-input-number v-model="item.delayTime" :controls='false' :min='0' :max='99' :precision="0" class="input-number" :class="{'is-first': !index || formData.executionOrder === '1'}"></el-input-number>
          <span v-if='!!index && formData.executionOrder === "0"' class="second-suffix">秒</span>
          <svg-icon icon-class="编辑" className='icon-edit' @click="editService(index)"/>
          <svg-icon icon-class="删除" className='icon-edit' @click="removeSerevice(index)"/>
        </div>
      </transition-group>
      <el-button v-if="formData.serviceSequence.length < maxSubscene" type="text" class="add-service" @click="addService" >
        <i class="el-icon-circle-plus"></i>
        添加服务
      </el-button>
      <el-divider></el-divider>
      <el-form-item v-if="formData.executionOrder === '0'" label="节点执行逻辑" prop="interruptionStrategyType" class="form-interruption bont">
        <el-select v-model="formData.interruptionStrategyType" placeholder="请选择">
          <el-option label="宽松策略" value="skip"></el-option>
          <el-option label="严格策略" value="terminate"></el-option>
        </el-select>
      </el-form-item>
      <div v-if="formData.executionOrder === '0'" class="interruption-directions">
        <div>1.严格策略：节点内所有服务执行成功，节点才视为执行成功；如果某个服务执行失败，则节点视为执行失败，且其余未执行的服务也不会再执行；</div>
        <div>2.宽松策略：如果某个服务执行失败，则自动跳过，执行节点内下一个服务。只要任意一个服务执行成功，节点即视为执行成功；如果节点内全部服务均执行失败，则节点视为执行失败；</div>
      </div>
    </el-form>
    <EditService :serviceData.sync='formData.serviceSequence[editIndex]' :show.sync='showEdit' @addService='confirmAdd' v-if='formData.serviceSequence'></EditService>
  </div>
</template>

<script>
import { deepClone } from '@/utils/helper/jsUtil'
import RuleNodeBaseClass from '@/components/ruleNode/RuleNodeBaseClass'
import EditService from './components/editService.vue'

export default {
  name: 'ServiceLibServiceNode',
  mixins: [RuleNodeBaseClass],
  components: {
    EditService
  },
  props: {
  },
  data() {
    return {
      maxSubscene: 10,
      formData: {
        executionOrder: '0',
        serviceSequence: [],
        interruptionStrategyType: ''
      },
      dragIndex: '',
      rules: {
        executionOrder: [{ required: false, message: '请选择服务执行策略', trigger: 'change' }],
        interruptionStrategyType: [{ required: false, message: ' ', trigger: 'change' }]
      },
      showEdit: false,
      editIndex: 0
    }
  },
  mounted() {
  },
  methods: {
    initValue() {
      const initFormData = this.initialForm ? deepClone(this.initialForm) : {}
      Object.assign(this.formData, initFormData)
      this.formData.serviceSequence = this.formData.serviceSequence || []
      this.formData.executionOrder = this.formData.executionOrder || '0'
    },
    addService() {
      if (this.formData.serviceSequence.length < this.maxSubscene) {
        this.showEdit = true
        this.editIndex = -1
      }
    },
    triggerExecutionOrder(val) {
      if (val === '1') {
        this.formData.serviceSequence.forEach(service => { service.delayTime = 0 })
        this.formData.interruptionStrategyType = ''
      }
    },
    confirmAdd(data) {
      this.formData.serviceSequence.push(data)
    },
    editService(index) {
      this.editIndex = index
      this.showEdit = true
    },
    removeSerevice(index) {
      if (this.formData.serviceSequence.length > 1) {
        this.formData.serviceSequence.splice(index, 1)
        this.formData.serviceSequence[0].delayTime = 0
      }
    },
    signalChange(emitData, signalItem) {
      Object.assign(signalItem, emitData)
    },
    getFormData() {
      const data = deepClone(this.formData)
      data.serviceSequence.forEach((service, index) => {
        index === 0 && (service.delayTime = 0)
      })
      return data
    },
    validateForm() {
      let isValid
      this.$refs.nodeForm.validate(valid => { isValid = valid })
      if (isValid && this.formData.serviceSequence.length === 0) {
        isValid = false
        this.$message.error('请至少选择一个服务！')
      }
      return isValid
    },
    shuffle() {
      this.formData.serviceSequence = this.$shuffle(this.formData.serviceSequence)
    },
    dragstart(e, index) {
      if (e.offsetX > 44) {
        e.preventDefault()
      } else {
        this.dragIndex = index
      }
    },
    dragenter(e, index) {
      e.preventDefault()
      // 避免源对象触发自身的dragenter事件
      if (this.dragIndex !== index) {
        const source = this.formData.serviceSequence[this.dragIndex]
        this.formData.serviceSequence.splice(this.dragIndex, 1)
        this.formData.serviceSequence.splice(index, 0, source)
        // 排序变化后目标对象的索引变成源对象的索引
        this.dragIndex = index
      }
    },
    dragover(e, index) {
      e.preventDefault()
    }
  }
}
</script>

<style lang="scss" scoped>
@import "~@/assets/styles/variables.scss";

.service-node {
  .service-title{
    margin-bottom: 16px;
  }
  .service-list {
    .service-item {
      background: $color-gray;
      margin-bottom: 8px;
      display: flex;
      .service-name{
        flex: 1 1 180px;
        line-height: 48px;
        height: 48px;
        overflow:hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
      }
      .select-execute{
        flex-shrink: 0;
        width: 140px;
        margin: 8px 0;
      }
      .type-suffix{
        color: #000;
        line-height: 48px;
        margin: 0 6px;
      }
      .input-number{
        flex-shrink: 0;
        width: 80px;
        margin: 8px 0;
        margin-right: -14px;
        &.is-first{
          display: none;
        }
      }
      .second-suffix{
        color: #A3A3A3;
        line-height: 48px;
        transform:translateX(-8px);
      }
      .sort-bg{
        cursor: move;
        width: 44px;
        height: 48px;
        background: url();
        background-repeat: no-repeat;
        background-position: 15px center;
        padding: 0 15px;
      }
      .icon-edit{
        color: #666;
        flex-shrink: 0;
        width: 16px;
        height: 48px;
        margin-left: 22px;
        cursor: pointer;
        &:last-child{
          margin-right: 15px;
        }
      }
    }
  }
  .add-service {
    font-size: 14px;
    .el-icon-circle-plus{
      font-size: 16px;
    }
  }
  .form-interruption{
    margin-bottom: 8px;
  }
  .interruption-directions{
    line-height: 20px;
    color: #a3a3a3;
  }
  .drag-move {
    transition: transform .3s;
  }
}
</style>
<style lang="scss">
.service-node .service-list .service-item .input-number{
  .el-input__inner{
    text-align: left;
  }
}
.service-node .bont{
  .el-form-item__label{
    font-weight: bold;
  }
}
</style>
